package com.sl.sdn.utils;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.stream.StreamUtil;
import cn.hutool.core.util.NumberUtil;
import com.sl.sdn.dto.OrganDTO;
import com.sl.sdn.dto.TransportLineNodeDTO;
import com.sl.sdn.enums.OrganTypeEnum;
import org.neo4j.driver.Record;
import org.neo4j.driver.internal.value.PathValue;
import org.neo4j.driver.types.Path;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class TransportLineUtil {
    private TransportLineUtil() {
    }

    public static TransportLineNodeDTO getTransportLine(Record record) {
        PathValue pathValue = (PathValue) record.get(0);
        Path path = pathValue.asPath();
        TransportLineNodeDTO dto = new TransportLineNodeDTO();
        // 读取节点数据
        List<OrganDTO> nodeList = StreamUtil.of(path.nodes())
                .map(node -> {
                    Map<String, Object> map = node.asMap();
                    OrganDTO organDTO = BeanUtil.toBeanIgnoreError(map, OrganDTO.class);
                    //取第一个标签作为类型
                    OrganTypeEnum organTypeEnum = OrganTypeEnum.valueOf(CollUtil.getFirst(node.labels()));
                    organDTO.setType(organTypeEnum.getCode());
                    //查询出来的数据，x：经度，y：纬度
                    organDTO.setLatitude(BeanUtil.getProperty(map.get("location"), "y"));
                    organDTO.setLongitude(BeanUtil.getProperty(map.get("location"), "x"));
                    return organDTO;
                })
                .collect(Collectors.toList());
        dto.setNodeList(nodeList);

        //提取关系中的 cost 数据，进行求和计算，算出该路线的总成本
        double cost = StreamUtil.of(path.relationships())
                .mapToDouble(relationship -> {
                    Map<String, Object> objectMap = relationship.asMap();
                    return Convert.toDouble(objectMap.get("cost"), 0d);
                }).sum();
        dto.setCost(cost);

        //取2位小数
        dto.setCost(NumberUtil.round(dto.getCost(), 2).doubleValue());
        return dto;
    }
}
